#Import necessary libraries
import geopandas as gpd
import pandas as pd
import requests
from pandas import json_normalize
from ipywidgets import FloatRangeSlider
import pydeck as pdf
import matplotlib.pyplot as plt
#Retrieve data from ACLED's API. Add your key and email in order to retrieve data
api = "https://api.acleddata.com/acled/read?key=addyourkey&email=addyouremail"
#Retrieve data for the African Continent - for more information on how to query the ACLED API, check the API Codebook
params = {
'region' : '1|2|3|4|5',
'actor1': 'Islamic State Sahel Province (ISSP):OR:actor2=Islamic State Sahel Province (ISSP)',
'limit': 0,
}
response = requests.get(api, params=params)
#Parse JSON data
data = response.json()
#Normalize the data
acled_data = json_normalize(data['data'])
#Print the dataset
display(acled_data)
| event_id_cnty | event_date | year | time_precision | disorder_type | event_type | sub_event_type | actor1 | assoc_actor_1 | inter1 | ... | location | latitude | longitude | geo_precision | source | source_scale | notes | fatalities | tags | timestamp | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | MLI33492 | 2024-12-11 | 2024 | 1 | Strategic developments | Strategic developments | Change to group/activity | Islamic State Sahel Province (ISSP) | Rebel group | ... | Doro | 16.1137 | -0.8606 | 2 | Al Zallaqa; Twitter; Undisclosed Source | Local partner-Other | Change to armed group: On 11 December 2024, a ... | 0 | 1734465911 | ||
| 1 | MLI33512 | 2024-12-10 | 2024 | 1 | Strategic developments | Strategic developments | Change to group/activity | Islamic State Sahel Province (ISSP) | Rebel group | ... | Tamarmat | 17.2000 | 2.8667 | 2 | Undisclosed Source | Local partner-Other | Movement of forces: On 10 December 2024, the p... | 0 | 1734387209 | ||
| 2 | MLI33511 | 2024-12-10 | 2024 | 1 | Strategic developments | Strategic developments | Change to group/activity | Islamic State Sahel Province (ISSP) | Rebel group | ... | Sahene | 17.2608 | 2.9919 | 2 | Undisclosed Source | Local partner-Other | Movement of forces: On 10 December 2024, the p... | 0 | 1734465911 | ||
| 3 | MLI33513 | 2024-12-10 | 2024 | 1 | Political violence | Battles | Armed clash | Islamic State Sahel Province (ISSP) | Rebel group | ... | In Delimane | 15.8685 | 1.5275 | 1 | Undisclosed Source | Local partner-Other | On 10 December 2024, some ISSP militants kille... | 1 | 1734465911 | ||
| 4 | NIR31210 | 2024-12-10 | 2024 | 1 | Political violence | Battles | Armed clash | Islamic State Sahel Province (ISSP) | Rebel group | ... | Petelkole | 13.9931 | 0.4199 | 1 | Aniamey; Forces Armees Nigeriennes; RFI | Other-National | On 10 December 2024, an armed group (likely IS... | 36 | 1734465914 | ||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2282 | MLI6340 | 2022-03-09 | 2022 | 2 | Political violence | Violence against civilians | Attack | Islamic State Sahel Province (ISSP) | Rebel group | ... | In Chinnana | 15.6063 | 3.3791 | 2 | aBamako; Undisclosed Source | Local partner-Other | Around 9 March 2022 (between 9 - 10 March), IS... | 18 | 1730156944 | ||
| 2283 | MLI6341 | 2022-03-09 | 2022 | 1 | Political violence | Violence against civilians | Attack | Islamic State Sahel Province (ISSP) | Rebel group | ... | In Farakraka | 15.8097 | 3.5529 | 1 | New media | On 9 March 2022, IS Sahel militants attacked a... | 10 | 1730156944 | |||
| 2284 | MLI6352 | 2022-03-09 | 2022 | 1 | Political violence | Battles | Non-state actor overtakes territory | Islamic State Sahel Province (ISSP) | Rebel group | ... | In Chinnana | 15.6063 | 3.3791 | 1 | aBamako; MSA Azawad; RFI; Undisclosed Source | Local partner-Other | On 9 March 2022, IS Sahel militants and MSA mi... | 8 | 1730156944 | ||
| 2285 | BFO6777 | 2022-03-09 | 2022 | 1 | Strategic developments | Strategic developments | Looting/property destruction | Islamic State Sahel Province (ISSP) | Rebel group | ... | Sambonaye | 14.1444 | 0.0527 | 1 | New media | Looting: On 9 March 2022, presumed ISSP milita... | 0 | 1730158770 | |||
| 2286 | MLI6329 | 2022-03-09 | 2022 | 1 | Political violence | Battles | Armed clash | Islamic State Sahel Province (ISSP) | Rebel group | ... | Tamalat | 15.7970 | 3.7095 | 1 | aBamako; Al Naba; MSA Azawad; Twitter; Undiscl... | Local partner-Other | On 9 March 2022, IS Sahel militants and MSA mi... | 60 | 1731445548 |
2287 rows × 31 columns
#Convert from DataFrame to GeoDataFrame
gdf = gpd.GeoDataFrame(acled_data, geometry=gpd.points_from_xy(acled_data.longitude, acled_data.latitude), crs='EPSG:4326')
#Convert object data type into numerical
gdf['year'] = pd.to_numeric(gdf['year'], errors='coerce')
gdf['fatalities'] = pd.to_numeric(gdf['fatalities'], errors='coerce')
gdf['longitude'] = pd.to_numeric(gdf['longitude'], errors='coerce')
gdf['latitude'] = pd.to_numeric(gdf['latitude'], errors='coerce')
# Create ScatterplotLayer
scatterplot_layer = pdk.Layer(
'ScatterplotLayer',
gdf,
get_position=['longitude', 'latitude'],
get_fill_color=[139, 0, 0], # Color in RGB
get_radius='fatalities * 2', # Scale radius based on fatalities
radius_min_pixels=1.5,
pickable=True, # Allow interactions with the points
)
# Create the map view to center the map in Niamey, Niger
view_state = pdk.ViewState(
latitude=13.5120,
longitude=2.1128,
zoom=4,
)
# Create the map and display the scatter_plot layer. Use the 'dark' basemap
map = pdk.Deck(
layers=[scatterplot_layer],
initial_view_state=view_state,
map_style='dark',
)
# Slider to control the year range
year_slider = FloatRangeSlider(
value=[1997, 2024],
min=1997,
max=2024,
step=1,
description="Year Range: ",
readout_format='.0f',
layout=Layout(width='50%')
)
# Link the year slider to filter the scatterplot layer
def update_map(change):
# Get selected range from slider
year_range = change['new']
# Filter data based on year range
filtered_data = gdf[(gdf['year'] >= year_range[0]) & (gdf['year'] <= year_range[1])]
# Update the ScatterplotLayer with the filtered data
map.layers[0].data = filtered_data
# Attach the slider's value change to the update function
year_slider.observe(update_map, names='value')
# Display the slider and map
display(year_slider)
map.show()
FloatRangeSlider(value=(1997.0, 2024.0), description='Year Range: ', layout=Layout(width='50%'), max=2024.0, m…